package com.sophialex.health.record.common.bind;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import org.eclipse.ui.part.ViewPart;

import com.sophialex.health.record.common.bind.swt.annotations.helper.ObjMaker;

public class ListPathCheckBinder extends CheckboxBindingUtil {

	@SuppressWarnings({ "null", "unchecked" })
	@Override
	protected Object computeBeanPropValue(Object bean, String[] beanPath) {
		String[] paths = beanPath;
		Object upper = bean;
		Pattern np = Pattern.compile("[0-9]+");

		Class<?> geniricType = null;
		for (int i = 0; i < paths.length; i++) {

			if (!np.matcher(paths[i]).matches()) {// paths[i]不是数字

				Object tmp = getFieldValue(upper, paths[i]);
				if (tmp == null) {// 还未初始化

					Method m = null;
					Class<?> clazz = null;
					Field field = null;
					try {
						m = upper.getClass().getDeclaredMethod(
								"get"
										+ Character.toUpperCase(paths[i]
												.charAt(0))
										+ paths[i].substring(1));
						clazz = m.getReturnType();
						if (List.class.isAssignableFrom(clazz)) {
							String gs = m.getGenericReturnType().toString();
							geniricType = Class.forName(gs.split("<")[1]
									.split(">")[0]);
						} else {
							geniricType = null;
						}
					} catch (Exception e) {
						e.printStackTrace();
					}

					// 若未得到getter,尝试直接访问字段
					// if (m == null) {
					// try {
					// field = upper.getClass().getDeclaredField(paths[i]);
					// clazz = field.getType();
					//
					// if (List.class.isAssignableFrom(clazz)) {
					// String gs = field.getGenericType().toString();
					// geniricType = Class.forName(gs.split("<")[1]
					// .split(">")[0]);
					// } else {
					// geniricType = null;
					// }
					//
					// } catch (Exception e) {
					// e.printStackTrace();
					// throw new BadBindingException("beanPath配置不正确！");
					// }
					// }
//					Constructor<?> c = null;
//					try {
//						c = clazz.getConstructor();
//					} catch (Exception e) {// 没有构造函数，那可能是Int,Long等基本类型
//						// e.printStackTrace();
//						System.out.println(clazz.getSimpleName() + "无缺省构造函数！");
//					}
					try {
//						if (clazz.equals(int.class)
//								|| clazz.equals(Integer.class)) {
//							tmp = 0;
//						} else if (clazz.equals(long.class)
//								|| clazz.equals(Long.class)) {
//							tmp = 0L;
//						} else {
//							c = clazz.getConstructor();
//							tmp = c.newInstance();
//						}
						tmp = ObjMaker.getInstance(clazz).newObject();
						setFieldValue(upper, paths[i], tmp);
					} catch (Exception e) {
						e.printStackTrace();
					}
				} else {
					if (List.class.isAssignableFrom(tmp.getClass())) {
						try {
							Method m = upper.getClass().getDeclaredMethod(
									"get"
											+ Character.toUpperCase(paths[i]
													.charAt(0))
											+ paths[i].substring(1));
							Class clazz = m.getReturnType();
							
								String gs = m.getGenericReturnType().toString();
								geniricType = Class.forName(gs.split("<")[1]
										.split(">")[0]);
							
						} catch (Exception e) {
							e.printStackTrace();
						}
					}else{
						geniricType = null;
					}
				}
				// setFieldValue(upper, paths[i], tmp);
				upper = tmp;
			} else {// 数字
				int elementIndex = Integer.parseInt(paths[i]);
				List list = (List) upper;
				if (elementIndex > list.size()) {
					try {
//						Constructor c = geniricType.getConstructor();
						ObjMaker maker = ObjMaker.getInstance(geniricType);
						int size = list.size();
						for (int ii = 0; ii < elementIndex-size; ii++) {
							list.add(maker.newObject());
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				upper = list.get(elementIndex - 1);
				int j = i + 1;
				for (; j < paths.length; j++) {
					if (np.matcher(paths[j]).matches())
						break;
				}
				if (j != paths.length) {
					geniricType = null;
				}

			}
		}
		return upper;
	}

	private void setFieldValue(Object o, String fieldName, Object value) {
		Field f = null;
		List<Field> fs = getFields(o.getClass(), true);
		for (Field f1 : fs) {
			if (f1.getName().equals(fieldName))
				f = f1;
		}
		if (f != null) {
			f.setAccessible(true);
			try {
				f.set(o, value);
			} catch (Exception e) {
				e.printStackTrace();
				// System.exit(-1);
			}
			return;
		}

		String name = "set" + Character.toUpperCase(fieldName.charAt(0))
				+ fieldName.substring(1);

		Method setter = null;
		try {

			setter = o.getClass().getMethod(name, value.getClass());

		} catch (Exception e1) {
			e1.printStackTrace();
			// System.exit(-1);// 没办法了，退出
		}
		try {

			setter.invoke(o, value);

		} catch (Exception e1) {
			e1.printStackTrace();
			// System.exit(-1);
		}

	}

	protected List<Field> getFields(Class<?> clazz, boolean isTop) {
		List<Field> r = new ArrayList<Field>();
		Field[] fs = clazz.getDeclaredFields();
		for (Field f : fs) {
			if (isTop) {// 第一层
				f.setAccessible(true);
				r.add(f);
			} else {// 当前正在处理view的超类
				if (isValidFiledOfBaseClazz(f)) {
					f.setAccessible(true);
					r.add(f);
				}
			}
		}
		Class<?> sc = clazz.getSuperclass();
		if (ViewPart.class.isAssignableFrom(sc)) {
			r.addAll(getFields(sc, false));
		}
		return r;
	}

	private boolean isValidFiledOfBaseClazz(Field f) {
		int m = f.getModifiers();
		if (Modifier.isProtected(m) || Modifier.isPublic(m))
			return true;
		return false;
	}
}
